package org.abettor.angleworm.media.rtp;

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.media.protocol.DataSource;
import javax.media.rtp.RTPManager;
import javax.media.rtp.ReceiveStream;
import javax.media.rtp.ReceiveStreamListener;
import javax.media.rtp.SessionAddress;
import javax.media.rtp.event.ByeEvent;
import javax.media.rtp.event.NewReceiveStreamEvent;
import javax.media.rtp.event.ReceiveStreamEvent;

public class RtpReceiver implements ReceiveStreamListener
{
	private InetAddress sourceAddr;
	private InetAddress localAddr;
	private int localPort;
	private RTPManager rtpMgr;
	private List<DataSource> dsList = Collections.synchronizedList(new ArrayList<DataSource>());

	/**
	 * 默认构造函数，根据给定本地绑定端口和媒体发送者的主机名称或IP地址构造接收程序实例
	 * @param senderAddr
	 * @param localPort
	 */
	public RtpReceiver(String senderAddr, int localPort)
	{
		this.localPort = localPort;
		try
		{
			localAddr = InetAddress.getLocalHost();
			sourceAddr = InetAddress.getByName(senderAddr);
		}
		catch(UnknownHostException e)
		{
			e.printStackTrace();
		}
	}

	/**
	 * 启动接收程序的接收动作
	 * @throws IOException
	 */
	public void start() throws IOException
	{
		SessionAddress saLocal = new SessionAddress(localAddr, localPort);
		SessionAddress saSource = new SessionAddress(sourceAddr, SessionAddress.ANY_PORT);
		rtpMgr = RTPManager.newInstance();
		rtpMgr.addReceiveStreamListener(this);
		try
		{
			rtpMgr.initialize(saLocal);
			rtpMgr.addTarget(saSource);
		}
		catch(Exception e)
		{
			rtpMgr.dispose();
			rtpMgr = null;
			throw new IOException(e);
		}
	}

	/**
	 * 停止接收媒体数据，并将媒体接收程序置为待销毁状态
	 */
	public void close()
	{
		if(rtpMgr != null)
		{
			rtpMgr.removeReceiveStreamListener(this);
			rtpMgr.dispose();
			rtpMgr = null;
		}
		dsList.clear();
	}

	/**
	 * @see javax.media.rtp.ReceiveStreamListener#update(ReceiveStreamEvent)
	 */
	@Override
	public synchronized void update(ReceiveStreamEvent event)
	{
		if(event instanceof NewReceiveStreamEvent)
		{
			NewReceiveStreamEvent nrse = (NewReceiveStreamEvent) event;
			ReceiveStream rs = nrse.getReceiveStream();
			DataSource ds = rs.getDataSource();
			dsList.add(ds);
		}
		else if(event instanceof ByeEvent)
		{
			close();
		}
	}

	/**
	 * 设定绑定地址
	 * @param bindAddr
	 */
	public void setBindAddress(String bindAddr)
	{
		try
		{
			localAddr = InetAddress.getByName(bindAddr);
		}
		catch(UnknownHostException e)
		{
			e.printStackTrace();
		}
	}

	/**
	 * 获取绑定地址
	 */
	public String getBindAddress()
	{
		return localAddr.getHostAddress();
	}
}
